﻿#include "study05.h"
// C/C++ 学习网站：https://legacy.cplusplus.com 注意旧版本（搜索）和新版本

template<typename any> // 模版（template）定义，any 为类型参数（可以随意命名，但一般为 T），可以替换为任意类型
void print(any x) {
    cout << x << endl;
}

template<typename T, size_t N> // 模版（template）定义，N 为整型常量参数，可以替换为任意整数
class MyArray {
private:
    T m_arr[N]; //ok
    size_t m_len = 0; // 有效成员变量实际长度
public:
    MyArray() { // 构造函数
        //cout << "MyArray<T " << N << "> constructor called." << endl;
        for (int i = 0; i < N; i++)
            m_arr[i] = i;
    }

    size_t get_length() const { return N; }
    //size_t get_m_len() const { return m_len; }

    void add_element(T element) { // 尾部添加成员函数
        m_arr[m_len++] = element;
    }

    T& operator[](int index) { // 重载 [] 运算符
        if (index < 0 || index > N - 1)
            throw std::out_of_range("Index out of range");  // throw 是 C++ 的异常处理关键字
        return m_arr[index];
    }

    void operator=(const MyArray<T, N>& other) { // 重载 = 运算符，拷贝类对象赋值运算符
        m_len = other.m_len;
        for (int i = 0; i < m_len; i++)
            m_arr[i] = other.m_arr[i];
    }

    void print() { // 打印类所有元素
        for (int i = 0; i < N; i++)
            cout << m_arr[i] << " ";
        cout << endl;
    }
    //protected: // 保护成员函数，仅在类内部可访问
};

void test_template()
{ // 模版（template）测试
    print_start("模版 template 类测试");
    print(10); // 调用模板函数，传入 int 类型参数
    print<double>(15.5); // 调用模板函数，传入 double 类型参数
    print<string>("test, words!"); // 调用模板函数，传入 string 类型参数
    float arr_f1[3] = { 1.1f, 2.2f, 3.3f }; // 定义 float 数组
    print(arr_f1); // 打印指针

    MyArray<int, 50>* arr1 = new MyArray<int, 50>; // 实例化堆区类
    for (int i = 0; i < 50; i++)
        arr1->add_element(i + 1); // 调用 add_element() 函数，尾部添加元素
    arr1->print(); // 调用 print() 函数，打印所有元素
    MyArray<string, 5> arr2; // 实例化栈区类
    cout << "arr1 len: " << arr1->get_length() << "    "
        << "arr2 len: " << arr2.get_length() << endl; // 调用 get_len() 函数，打印数组长度
    arr2.add_element("my"); // 调用 add_element() 函数，尾部添加元素
    arr2.add_element(" name"); // 调用 add_element() 函数，尾部添加元素
    arr2.add_element(" is"); // 调用 add_element() 函数，尾部添加元素
    arr2.add_element(" sunny"); // 调用 add_element() 函数，尾部添加元素
    cout << arr2[0] << arr2[1] << arr2[2] << arr2[3] << endl; // 调用 [] 运算符，打印元素
    MyArray<string, 5> arr3;
    arr3[0] = "hello"; // 调用 [] 运算符，赋值元素
    arr3[1] = "world"; // 调用 [] 运算符，赋值元素
    cout << arr3[2] << 'a' << arr3[3] << endl;
    // 调用 [] 运算符，打印元素，字符串没有值则不会打印（因为构造函数初始化为 0）
//arr3.print(); // 调用 print() 函数，打印所有元素
    cout << arr3[0] << ' ' << arr3[1] << endl;

    delete arr1; // 释放堆区类内存
    print_end("模版 template 类测试");
}
